package com.qys.livesMall.shortVideo.controller.sys;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qys.livesMall.app.user.model.entity.H2AppUser;
import com.qys.livesMall.app.user.service.IH2AppUserService;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.finance.enums.AccountBusinessTypeEnum;
import com.qys.livesMall.finance.model.dto.FinancePayDTO;
import com.qys.livesMall.finance.service.FinanceBusinessService;
import com.qys.livesMall.finance.util.BusinessNoUtil;
import com.qys.livesMall.framework.utils.SecurityUtils;
import com.qys.livesMall.shortVideo.model.dto.sys.SysShortVideoAuditDTO;
import com.qys.livesMall.shortVideo.model.dto.sys.SysShortVideoQueryDTO;
import com.qys.livesMall.shortVideo.model.dto.sys.SysShortVideoSaveDTO;
import com.qys.livesMall.shortVideo.model.entity.H2ShortVideo;
import com.qys.livesMall.shortVideo.model.entity.H2ShortVideoCategory;
import com.qys.livesMall.shortVideo.model.vo.app.AppShortVideoTagVO;
import com.qys.livesMall.shortVideo.model.vo.sys.SysShortVideoVO;
import com.qys.livesMall.shortVideo.model.vo.sys.VideoStatisticsVO;
import com.qys.livesMall.shortVideo.service.IH2ShortVideoCategoryService;
import com.qys.livesMall.shortVideo.service.IH2ShortVideoService;
import com.qys.livesMall.system.model.vo.sys.H2SysShareConfigVO;
import com.qys.livesMall.system.service.SysShareConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 短视频信息 前端控制器
 * </p>
 *
 * @author dp
 * @since 2023-05-04
 */
@RestController
@RequestMapping("/sys/short/video")
@Tag(name = "后台管理-短视频信息")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class H2ShortVideoController {

    private final IH2ShortVideoService shortVideoService;
    private final IH2ShortVideoCategoryService shortVideoCategoryService;
    private final FinanceBusinessService financeBusinessService;
    private final IH2AppUserService userService;
    private final SysShareConfigService shareConfigService;


    @PostMapping("/page")
    @Operation(summary = "分页查询短视频信息")
    public R<Page<SysShortVideoVO>> pageBySystem(@RequestBody SysShortVideoQueryDTO sysShortVideoQueryDTO) {
        return R.ok(shortVideoService.pageBySystem(sysShortVideoQueryDTO));
    }

    @PostMapping("/add")
    @Operation(summary = "新增短视频信息")
    public R<Void> insertVideo(@RequestBody @Validated SysShortVideoSaveDTO videoSaveDTO) {
        shortVideoService.saveVideoBySystem(videoSaveDTO);
        return R.ok();
    }

    @PutMapping("/edit")
    @Operation(summary = "修改短视频信息")
    public R<Void> editVideo(@RequestBody @Validated SysShortVideoSaveDTO videoSaveDTO) {
        shortVideoService.saveVideoBySystem(videoSaveDTO);
        return R.ok();
    }

    @DeleteMapping("/remove")
    @Operation(summary = "根据id删除短视频信息")
    public R<Void> removeById(@RequestBody @Validated SysShortVideoAuditDTO auditDTO) {
        shortVideoService.removeByIds(auditDTO.getIds());
        return R.ok();
    }

    @DeleteMapping("/audit")
    @Operation(summary = "审核短视频信息")
    public R<Void> audit(@RequestBody @Validated SysShortVideoAuditDTO auditDTO) {

        List<H2ShortVideo> videos = new ArrayList<>(auditDTO.getIds().size());
        auditDTO.getIds().forEach(id -> {
            H2ShortVideo video = new H2ShortVideo();
            video.setId(id);
            video.setStatus(auditDTO.getStatus());
            video.setAuditUser(SecurityUtils.getLoginUser().getNickName());
            video.setBonus(auditDTO.getBonus());
            videos.add(video);
        });
        if(auditDTO.getBonus()!=null&&auditDTO.getBonus().compareTo(new BigDecimal("0"))>0){
            List<H2ShortVideo> videoList=shortVideoService.listByIds(auditDTO.getIds());
            if (!CollectionUtils.isEmpty(videoList)){
                for(H2ShortVideo video:videoList){
                    //上级分佣
                    BigDecimal total = this.superiorCommission(video.getUserId(), auditDTO.getBonus());
                    //用户收益=总金额-上级分佣
                    FinancePayDTO payDTO = new FinancePayDTO();
                    payDTO.setUserId(video.getUserId());
                    payDTO.setBusinessNo(BusinessNoUtil.get(AccountBusinessTypeEnum.SELF_VIDEO_REWARD));
                    payDTO.setAmountIncurred(auditDTO.getBonus().subtract(total));
                    payDTO.setBusinessType(AccountBusinessTypeEnum.SELF_VIDEO_REWARD);
                    financeBusinessService.pay(payDTO);
                }
            }

        }
        shortVideoService.updateBatchById(videos);
        return R.ok();
    }

    public BigDecimal superiorCommission(Long videoUserId, BigDecimal bonus) {

        List<H2SysShareConfigVO> config = shareConfigService.list((byte) 1);
        if (CollectionUtils.isEmpty(config)) {
            log.info("视频审核通过上级分佣失败，没有配置");
            return BigDecimal.ZERO;
        }

        H2AppUser appUser = userService.getById(videoUserId);
        if(appUser == null){
            log.info("视频审核通过上级分佣失败, 错误的用户id");
            return BigDecimal.ZERO;
        }

        int index = 0;
        Map<String, BigDecimal> parentIncome = new HashMap<>();
        while (appUser.getSuperior() != null && index < config.size()) {
            appUser = userService.getById(appUser.getSuperior());
            if (null == appUser) {
                log.info("视频审核通过上级分佣失败, 上级不存在");
                return BigDecimal.ZERO;
            }

            //分红比例
            H2SysShareConfigVO configVO = config.get(index);
            BigDecimal dividendRatio = configVO.getDividendRatio();

            //计算奖励
            BigDecimal reward = bonus.multiply(dividendRatio).setScale(4, RoundingMode.DOWN);
            parentIncome.put(appUser.getId(), reward);

            index++;
        }

        parentIncome.forEach((userId, reward) -> {
            FinancePayDTO payDTO = new FinancePayDTO();
            payDTO.setUserId(Long.valueOf(userId));
            payDTO.setBusinessNo(BusinessNoUtil.get(AccountBusinessTypeEnum.VIDEO_REWARD));
            payDTO.setAmountIncurred(reward);
            payDTO.setBusinessType(AccountBusinessTypeEnum.VIDEO_REWARD);
            financeBusinessService.pay(payDTO);
        });

        BigDecimal total = parentIncome.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        log.info("视频审核通过上级分佣成功, 总计:{}", total);
        return total;
    }

    /**
     * 获取视频标签列表
     */
    @GetMapping(value = "/videoTagList")
    @Operation(summary = "获取视频标签列表")
    public R<List<AppShortVideoTagVO>> dictType() {

        LambdaQueryWrapper<H2ShortVideoCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(H2ShortVideoCategory::getDeleted, 0)
                .orderByAsc(H2ShortVideoCategory::getSort);
        List<H2ShortVideoCategory> h2ShortVideoCategories = shortVideoCategoryService.list(queryWrapper);

        List<AppShortVideoTagVO> list = new ArrayList<>();
        h2ShortVideoCategories.forEach(e -> {
            AppShortVideoTagVO videoTagVO = new AppShortVideoTagVO();
            videoTagVO.setTagCode(e.getId());
            videoTagVO.setTagName(e.getName());
            list.add(videoTagVO);
        });
        return R.ok(list);
    }

    @GetMapping("/videoStatistics")
    @Operation(summary = "短视频数据统计")
    public R<VideoStatisticsVO> videoStatistics(){
        VideoStatisticsVO videoStatisticsVO = new VideoStatisticsVO();
        LambdaQueryWrapper<H2ShortVideo> queryWrapper = Wrappers.<H2ShortVideo>lambdaQuery().eq(H2ShortVideo::getStatus, 1);
        videoStatisticsVO.setVideoTotal((int)shortVideoService.count(queryWrapper));
        videoStatisticsVO.setNewToday((int)shortVideoService.count(queryWrapper.gt(H2ShortVideo::getCreateTime, LocalDate.now().atStartOfDay())));
        return R.ok(videoStatisticsVO);
    }
}
